package com.example.demo7pdf.util;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.layout.font.FontProvider;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class PdfItext {

    public static void main(String[] args) throws Exception {
        //模板内容填充参数
        Context context = new Context();
        context.setVariable("name2", "晨曦话java");
        context.setVariable("name1", "晨曦话三国");
        PdfItext.htmlToPdf("/templates/template.html", "/mnt/pdf/", System.currentTimeMillis() + "_temp.pdf", context);
    }

    /**
     * @param templatePath 模板全路径
     * @param path         生成pdf文件夹
     * @param fileName     生成pdf文件名
     * @param context      填充参数
     */
    public static void htmlToPdf(String templatePath, String path, String fileName, Context context) {
        String linuxPath = PdfItext.getFileAbsolutePath(templatePath, "/mnt/pdf/templates/template1.html", true);
        ConverterProperties converterProperties = new ConverterProperties();
        FontProvider dfp = new DefaultFontProvider();
//      dfp.addSystemFonts(); //添加中文字体库 方式a   -window环境有自带字体 linux环境需要安装中文字体，可参考 https://www.zhihu.com/question/423159370/answer/2706867741
        //添加中文字体库 方式b 使用项目导入的字体库 （已验证linux环境不安装中文字体，能正常显示中文）
        dfp.addFont(getFileAbsolutePath("/templates/simsun.ttf", "/mnt/pdf/templates/simsun.ttf", false));
        converterProperties.setFontProvider(dfp);
        //将本地的模板转换成字符串
        String htmlStr = toHtmlString(new File(linuxPath));
        //模板参数替换
        String replaceHtmlStr = new TemplateEngine().process(htmlStr, context);
        File destDir = new File(path);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        try (OutputStream out = new FileOutputStream(new File(path + fileName))) {
            HtmlConverter.convertToPdf(replaceHtmlStr, out, converterProperties);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("pdf转换异常3{}" + e);
        }
    }

    /**
     * @param templatePath 模板全路径
     * @param path         生成pdf文件夹
     * @param fileName     生成pdf文件名
     * @param context      填充参数
     */
    public static ByteArrayOutputStream htmlToPdfOutputStream(String templatePath, String path, String fileName, Context context) {
        String linuxPath = PdfItext.getFileAbsolutePath(templatePath, "/mnt/pdf/templates/template1.html", true);
        ConverterProperties converterProperties = new ConverterProperties();
        FontProvider dfp = new DefaultFontProvider();
//      dfp.addSystemFonts(); //添加中文字体库 方式a   -window环境有自带字体 linux环境需要安装中文字体，可参考 https://www.zhihu.com/question/423159370/answer/2706867741
        //添加中文字体库 方式b 使用项目导入的字体库 （已验证linux环境不安装中文字体，能正常显示中文）
        dfp.addFont(getFileAbsolutePath("/templates/simsun.ttf", "/mnt/pdf/templates/simsun.ttf", false));
        converterProperties.setFontProvider(dfp);
        //将本地的模板转换成字符串
        String htmlStr = toHtmlString(new File(linuxPath));
        //模板参数替换
        String replaceHtmlStr = new TemplateEngine().process(htmlStr, context);
        File destDir = new File(path);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            HtmlConverter.convertToPdf(replaceHtmlStr, out, converterProperties);
            return out;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("pdf转换异常3{}" + e);
        }
        return null;
    }

    /**
     * 读取本地html文件里的html代码
     *
     * @param file File file=new File("文件的绝对路径")
     * @return
     */
    public static String toHtmlString(File file) {
        // 获取HTML文件流
        StringBuffer htmlSb = new StringBuffer();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(file), "utf-8"));
            while (br.ready()) {
                htmlSb.append(br.readLine());
            }
            br.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // HTML文件字符串
        String htmlStr = htmlSb.toString();
        // 返回经过清洁的html文本
        return htmlStr;
    }

    /**
     * 解决linux下运行jar，无法加载jar包下文件（window环境能正常加载）
     *
     * @param templatePath 模板路径 传相对路径 比如 /templates/template.htm
     * @param createPath   生成路径  比如  /mnt/pdf/templates/template.html
     * @param isConvered   是否覆盖模板，默认false.  如模板变化，需覆盖生成
     * @return 返回的路径就是放在linux服务器上的文件路径
     */
    public static String getFileAbsolutePath(String templatePath, String createPath, boolean isConvered) {
        try {
            // 创建临时文件，获取jar里面的配置文件
            File file = new File(createPath);
            if (file.exists() && !isConvered) {
                return file.getAbsolutePath();
            } else {
                new File(file.getParent()).mkdirs();

            }
            InputStream inputStream = null;
            try {
                ClassPathResource resource = new ClassPathResource(templatePath);
                inputStream = resource.getInputStream();
                byte[] buffer = new byte[inputStream.available()];
                inputStream.read(buffer);
                OutputStream outStream = new FileOutputStream(file);
                outStream.write(buffer);
                return file.getAbsolutePath();
            } finally {
                IOUtils.closeQuietly(inputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("FileUtil getFilePath Fail cause by:" + e);
        }
        return null;
    }

    public static void htmlToPdfExport(String templatePath, String path, String fileName, Context context, HttpServletResponse response) {
        String filename = System.currentTimeMillis() + "_temp.pdf";
        ByteArrayOutputStream byteArrayOutputStream = PdfItext.htmlToPdfOutputStream(templatePath, path, fileName, context);
        try {
            byte[] buffer = byteArrayOutputStream.toByteArray();
            InputStream resourceAsStream = new ByteArrayInputStream(buffer);
            String codedFileName = new String(filename.getBytes("gbk"), "iso-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + codedFileName);
            // 响应类型,编码
            response.setContentType("application/octet-stream;charset=UTF-8");
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
